package com.jsftoolkit.gen.builder;

import com.jsftoolkit.gen.info.ClassInfo;

/**
 * Utility class for building {@link ClassInfo} instances.
 * 
 * @author noah
 * 
 * @param <T>
 *            the class subclassing this class so chaining will be available for
 *            subclass methods.
 */
@SuppressWarnings("unchecked")
public abstract class ClassBuilder<T extends ClassBuilder> {

	private final ClassInfo info;

	/**
	 * 
	 * @param info
	 *            the {@link ClassInfo} subclass to operate on.
	 */
	public ClassBuilder(ClassInfo info) {
		this.info = info;
	}

	/**
	 * Specifies the package.
	 * 
	 * @param _package
	 *            the package the class is in
	 * @return this
	 */
	public T in(String _package) {
		info.setPackage(_package);
		return (T) this;
	}

	/**
	 * Specifies the class name.
	 * 
	 * @param className
	 *            the name of the class being described
	 * @return this
	 */
	public T named(String className) {
		info.setClassName(className);
		return (T) this;
	}

	/**
	 * Specifies that the class is abstract.
	 * 
	 * @return this
	 */
	public T abstractClass() {
		info.setAbstract(true);
		return (T) this;
	}

	/**
	 * Specifies the interfaces the class implements.
	 * 
	 * @param interfaces
	 * @return this
	 */
	public T implementing(Class... interfaces) {
		for (Class o : interfaces) {
			if (!o.isInterface()) {
				throw new IllegalArgumentException(o.getCanonicalName()
						+ " is not an interface.");
			}
			info.addInterface(o);
		}
		return (T) this;
	}

	/**
	 * Specifies the imports the class needs. See {@link ClassInfo#getImports()}
	 * 
	 * @param imports
	 * @return this
	 */
	public T requiring(Class... imports) {
		for (Class o : imports) {
			info.addImport(o);
		}
		return (T) this;
	}

	/**
	 * 
	 * @return the {@link ClassInfo} instance being operated on
	 */
	protected ClassInfo getInfo() {
		return info;
	}

}
